<template>
  <div id="editCode-alls">
    <div
      id="editCode-leftFrame"
      @mousemove="moveIntoCode"
      @mouseleave="moveOutCode"
    >
      <!-- 代码栏 -->
      <el-input
        type="textarea"
        :placeholder="editCodePlaceholder"
        v-model="textareaLeft"
        class="editCode-leftFrame--txtArea"
        ref="codeTxt"
        @input="changeCode"
        @keydown.native="textareaTabIndent($event)"
      >
      </el-input>
      <!-- 代码栏右上操作栏 -->
      <div
        class="editCode-leftFrame--topOperate"
        @click="copyCode"
        ref="copyCode"
        data-copy-code-test="复制"
        v-if="copyFlag"
      ></div>
    </div>
    <div id="editCode-operateLeft">
      <el-button
        type="primary"
        style="height: 40px"
        @click="
          revertCode();
          clearCode();
        "
        @clearCode="clearCode"
        v-if="clearCodeBtn"
        >{{ clearCodeBtnText }}</el-button
      >
      <el-switch
        v-model="modelText"
        :active-text="activeTxt"
        :inactive-text="inactiveTxt"
        @change="stateChange"
        v-if="changeModelBtn"
        class="editCode-operateLeft--changeModel__switch"
      >
      </el-switch>
      <!-- 操作栏位插槽 -->
      <slot name="codeEdit_code_operate"></slot>
    </div>
    <vertical-line
      size="12"
      :text="devideTxt"
      :divideTextTopDistance="divideTextTopDistance"
      v-if="needDivLine"
    ></vertical-line>
    <div id="editCode-operateRight">
      <p style="white-space: nowrap; font-size: 15px" v-if="displayResultText">
        运行结果：
      </p>
      <!-- 结果栏位插槽 -->
      <slot name="codeEdit_result_operate"></slot>
    </div>
    <div id="editCode-rightFrame">
      <!-- 给iframe加入scolling="no"相当于加入overflow: hidden; 隐藏部分无法显示 -->
      <iframe
        src=""
        frameborder="0"
        id="editCode-rightFrame--code_iframe"
        ref="rightFrame"
        scrolling="auto"
      >
      </iframe>
    </div>
  </div>
</template>

<script>
// @ is an alias to /src
import verticalLine from "@/components/verticalLine.vue";
export default {
  name: "editCode",
  components: {
    verticalLine,
  },
  props: {
    // 从分割线上的字的上方偏移量
    divideTextTopDistance: {
      type: String,
      default: "10%",
    },
    // 模式转化开关是否出现
    changeModelBtn: {
      type: Boolean,
      default: true,
    },
    // 还原按钮是否出现
    clearCodeBtn: {
      type: Boolean,
      default: true,
    },
    // 还原按钮上面的字
    clearCodeBtnText: {
      type: String,
      default: "还原",
    },
    // 左侧代码编辑框内的内容的placeholder
    editCodePlaceholder: {
      type: String,
      default: "请输入内容",
    },
    // 是否需要分隔线栏
    needDivLine: {
      type: Boolean,
      default: true,
    },
    // 是否需要“运行结果：”这几个字
    displayResultText: {
      type: Boolean,
      default: true,
    },
    // 分割线的文字
    devideTxt: {
      type: String,
      default: "左侧是代码区，右侧是运行结果",
    },
    // 初始CSS样式
    cssText_start: {
      type: String,
      default: "",
    },
    // 初始HTML样式
    htmlText_start: {
      type: String,
      default: "",
    },
    // 恢复原始代码的时候，同时执行的函数
    clearCode: {
      type: Function,
      default: () => {},
    },
    // 左侧代码栏的字体大小
    fontSize: {
      type: [Number, String],
    },
    // 是否加入本段注释
    iframe_cssNote: {
      type: Boolean,
      default: true,
    },
    // 是否加入通用样式 * {...}
    iframe_common_cssText: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      copyFlag: false,
      // 找到iframe元素
      elementFrame: "",
      textareaLeft: "",
      // CSS、HTML的中间变量
      tempTXT: {},
      // 开关，夜间模式/日间模式
      modelText: false,
      // 开关的两种模式
      inactiveTxt: "",
      activeTxt: "夜间模式",
    };
  },
  methods: {
    // 按下tab键，不让其切换元素，暂时无其他功能
    textareaTabIndent(e) {
      if (e.keyCode === 9) {
        if (!this.textareaLeft) {
          this.textareaLeft = "";
        }
        // 阻止默认切换元素的行为
        if (e && e.preventDefault) {
          e.preventDefault();
        } else {
          // 兼容IE浏览器
          window.event.returnValue = false;
        }
      }
    },
    // 移入代码区
    moveIntoCode() {
      this.copyFlag = true;
    },
    // 移出代码区
    moveOutCode() {
      this.copyFlag = false;
    },
    // 代码区更改的时候更改字样
    changeCode() {
      this.$refs.copyCode.dataset.copyCodeTest = "复制";
    },
    // 夜间、日间开关
    stateChange() {
      if (!this.modelText) {
        this.$refs.codeTxt.$el.children[0].style.mixBlendMode = "normal";
        this.inactiveTxt = "";
        this.activeTxt = "夜间模式";
      } else {
        this.$refs.codeTxt.$el.children[0].style.mixBlendMode = "difference";
        this.activeTxt = "";
        this.inactiveTxt = "日间模式";
      }
    },
    // 还原代码
    clearable() {
      this.textareaLeft = `<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style type="text/css">
    ${
      this.iframe_common_cssText
        ? `* {
      padding: 0;
      margin: 0;
      text-decoration: none;
      list-style: none;
      box-sizing: border-box;
    }`
        : ""
    }
    ${
      this.iframe_cssNote
        ? `/* 加入body这段代码是为了使得iframe内部的滚动条样式与左侧代码区一致 */`
        : ""
    }
    body {
      overflow: auto;
    }
    body::-webkit-scrollbar {
      width: 6px;
      background-color: transparent;
      height: 0;
    }
    body::-webkit-scrollbar-thumb {
      width: 99%;
      border-radius: 5px;
      background-color: rgba(144, 146, 152, 0.3);
    }
    ${this.tempTXT.tcssText_start}
    </style>
</head>
<body>
    <div>
      ${this.tempTXT.thtmlText_start}
    </div>
</body>

</html>`;
    },
    // 点击复制代码区域
    copyCode() {
      const clipboardObj = navigator.clipboard;
      if (clipboardObj) {
        clipboardObj.writeText(this.textareaLeft);
      } else {
        // 兼容IE浏览器
        this.$refs.copyCode.select();
        document.execCommand("Copy");
      }
      console.log(this.$refs.copyCode.dataset);
      this.$refs.copyCode.dataset.copyCodeTest = "复制成功";
    },
    // 初始化页面
    initPage() {
      this.$refs.codeTxt.$el.children[0].style.fontSize = this.fontSize + "px";
      // 能不操作元素就不操作元素，会影响其他页面，且影响效率
      this.$refs.rightFrame.innerHTML = this.textareaLeft;
      // innerHtml：设置或获取 HTML 语法表示的元素的后代。所以 script 标签里的内容还是识别识别不了
    },
    init_iframe() {
      this.$refs.rightFrame.srcdoc = this.textareaLeft;
    },
    // 清除写过的代码到默认状态
    revertCode() {
      this.tempTXT.thtmlText_start = this.htmlText_start;
      this.tempTXT.tcssText_start = this.cssText_start;
      this.clearable();
    },
    // 运行警告
    warning() {
      console.warn("最好在此简易代码编辑器组件外面套一层盒子，以限制宽高");
      if (
        typeof this.fontSize == "string" &&
        (this.fontSize.slice(-2) == "px" || this.fontSize.slice(-2) == "PX")
      ) {
        const PXnum = this.fontSize.split("");
        PXnum.splice(-2);
        console.error(
          `editCode组件的fontSize属性，输入数字 ${PXnum.join(
            ""
          )} 或者字符串 "${PXnum.join("")}" 即可`
        );
        return false;
      }
      if (this.fontSize < 12) {
        console.warn("字体太小，部分浏览器会有差异，最好调整字体到12px以上！");
      } else if (this.fontSize > 100) {
        console.warn("字体太大，部分浏览器会有差异，最好调整字体到50px以下！");
      }
    },
  },
  watch: {
    textareaLeft: {
      handler(n) {
        if (n) {
          // console.log(n.split(`\n`)); // qu
          this.initPage();
          this.init_iframe();
        }
      },
      deep: true,
    },
    htmlText_start: {
      handler(n) {
        this.tempTXT.thtmlText_start = n;
      },
      deep: true,
      immediate: true,
    },
    cssText_start: {
      handler(n) {
        this.tempTXT.tcssText_start = n;
      },
      deep: true,
      immediate: true,
    },
  },
  created() {
    this.warning();
    this.tempTXT = {
      tcssText_start: this.cssText_start,
      thtmlText_start: this.htmlText_start,
    };
  },
  mounted() {
    this.textareaLeft = `<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style type="text/css">
    ${
      this.iframe_common_cssText
        ? `* {
      padding: 0;
      margin: 0;
      text-decoration: none;
      list-style: none;
      box-sizing: border-box;
    }`
        : ""
    }
    ${
      this.iframe_cssNote
        ? `/* 加入body这段代码是为了使得iframe内部的滚动条样式与左侧代码区一致 */`
        : ""
    }
    body {
      overflow: auto;
    }
    body::-webkit-scrollbar {
      width: 6px;
      background-color: transparent;
      height: 0;
    }
    body::-webkit-scrollbar-thumb {
      width: 99%;
      border-radius: 5px;
      background-color: rgba(144, 146, 152, 0.3);
    }
    ${this.tempTXT.tcssText_start}
    </style>
</head>
<body>
    <div>
      ${this.tempTXT.thtmlText_start}
    </div>
</body>

</html>`;
    this.initPage();
    this.init_iframe();
  },
};
</script>
<style lang="scss" scoped>
#editCode-alls {
  width: 100%;
  height: 100%;
  min-height: 350px;
  display: flex;
  justify-content: space-between;
  border: 1px solid;
  border-radius: 4px;
  #editCode-leftFrame,
  #editCode-rightFrame {
    width: 45%;
    position: relative;
    border-radius: 4px;
  }
  #editCode-operateLeft {
    display: flex;
    flex-flow: column;
    .editCode-operateLeft--changeModel__switch {
      margin-top: 10px;
      width: 100px;
      &::v-deep .el-switch__label--left {
        margin-right: 0;
      }
      &::v-deep .el-switch__label--right {
        margin-left: 0;
      }
      &::v-deep .el-switch__core {
        min-width: 40px;
      }
    }
  }
}
#editCode-leftFrame {
  .editCode-leftFrame--topOperate {
    position: absolute;
    top: 7px;
    right: 14px;
    font-size: 14px;
    color: #ffffff;
    background-color: #9999aa;
    border-radius: 4px;
    cursor: pointer;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05), 0 2px 4px rgba(0, 0, 0, 0.05);
    padding: 2px 8px;
    &::after {
      content: attr(data-copy-code-test);
    }
  }
}
#editCode-rightFrame--code_iframe {
  width: 100%;
  height: 100%;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
// 文本框及滚动条样式
.editCode-leftFrame--txtArea {
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  height: 100%;
  color: #383a42;
  background-color: #f8f8f8; // 本身不生效，但是是为了子集盒子的mix-blend-mode命令生效
  font-family: Source Code Pro, DejaVu Sans Mono, Ubuntu Mono, Anonymous Pro,
    Droid Sans Mono, Menlo, Monaco, Consolas, Inconsolata, Courier, monospace,
    PingFang SC, Microsoft YaHei, sans-serif;
  // Menlo, Monaco, Consolas, "Courier New", monospace;
  &::v-deep textarea {
    height: 100%;
    // textarea禁止拖拽
    resize: none;
    font-size: 15px;
    background-color: #f8f8f8;
    font-weight: 900;
    mix-blend-mode: normal; // 想要生效，父级盒子必须要有底色，也就是background-color
    &::-webkit-scrollbar {
      width: 6px;
      background-color: transparent;
      height: 0;
    }
    &::-webkit-scrollbar-thumb {
      width: 99%;
      border-radius: 5px;
      background-color: rgba(144, 146, 152, 0.3);
    }
  }
}
</style>
